import {useAuthStore} from "@/store";
import {commons} from "@/utils/commons";

const user = useAuthStore()
// 从 vue 中引入 customRef 和 ref
import {customRef, ref} from "vue"

export const utils = {
    /**
     * auth跳转
     */
    authRoute: (url: string, params = {}) => {
        if (!user.token) {
            commons.showModelNoCancel('请先登录', () => {
                uni.navigateTo({
                    url: '/pages/login/wx-login'
                })
            })
        } else {
            uni.navigateTo({
                url: url,
            })
        }
    },

    /**
     * 数组拆分
     * @param array
     * @param subGroupLength
     */
    getNewArray: (array: [], subGroupLength: number) => {
        let index = 0;
        let newArray = [];
        while (index < array.length) {
            newArray.push(array.slice(index, index += subGroupLength));
        }
        return newArray;
    },

    /**
     * 返回数组中指定的一列
     * @param input 数组
     * @param columnKey 指定的列
     * @return {*[]}
     * @constructor
     */
    arrayColumn: (input: any, columnKey: string) => {
        let result = []
        for (let i = 0; i < input.length; i++) {
            result.push(input[i][columnKey])
        }
        return result
    },

    /**
     * 对象转数组
     * @return {*[]}
     * @param obj
     */
    objectToArray: (obj: any) => {
        let result = []
        for (let i in obj) {
            result.push(obj[i])
        }
        return result
    },

    /**
     * 判断指定元素是否在数组中
     * @param needle
     * @param haystack
     * @return {boolean}
     */
    inArray: (needle: string, haystack: any) => {
        for (let i in haystack) {
            if (haystack[i] == needle) return true
        }
        return false
    },

    /**
     * 图片预览
     * @param urls
     * @param index
     */
    previewImage: (urls: [], index: number) => {
        if (Array.isArray(urls)) {
            // 如果是多图预览
            uni.previewImage({
                current: index, //预览图片的下标
                urls: urls, //预览图片的地址，必须要数组形式，如果不是数组形式就转换成数组形式就可以
                loop: true, // 是否可循环预览
                indicator: 'number' //指示器
            })
        } else {
            // 如果是单图预览
            let arr: any = []
            arr.push(urls)
            uni.previewImage({
                current: 0,
                urls: arr
            })
        }
    },

    /**
     * 数字运算（主要用于小数点精度问题）
     * @param {number} a 前面的值
     * @param {"+"|"-"|"*"|"/"} type 计算方式
     * @param {number} b 后面的值
     * @example
     * ```js
     * // 可链式调用
     * const res = computeNumber(1.3, "-", 1.2).next("+", 1.5).next("*", 2.3).next("/", 0.2).result;
     * console.log(res);
     * ```
     */
    computeNumber(a: any, type: any, b: any) {
        /**
         * 获取数字小数点的长度
         * @param {number} n 数字
         */
        function getDecimalLength(n: any) {
            const decimal = n.toString().split(".")[1]
            return decimal ? decimal.length : 0
        }

        /**
         * 修正小数点
         * @description 防止出现 `33.33333*100000 = 3333332.9999999995` && `33.33*10 = 333.29999999999995` 这类情况做的处理
         * @param {number} n
         * @param precision
         */
        const amend = (n: any, precision = 15) => parseFloat(Number(n).toPrecision(precision))
        const power = Math.pow(10, Math.max(getDecimalLength(a), getDecimalLength(b)))
        let result = 0

        a = amend(a * power)
        b = amend(b * power)

        switch (type) {
            case "+":
                result = (a + b) / power
                break
            case "-":
                result = (a - b) / power
                break
            case "*":
                result = (a * b) / (power * power)
                break
            case "/":
                result = a / b
                break
        }

        result = amend(result)

        return {
            /** 计算结果 */
            result,
            /**
             * 继续计算
             * @param {"+"|"-"|"*"|"/"} nextType 继续计算方式
             * @param {number} nextValue 继续计算的值
             */
            next(nextType: any, nextValue: any) {
                return utils.computeNumber(result, nextType, nextValue)
            },
        }
    }

}


